/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.blue.jogl;

import com.jogamp.opengl.util.FPSAnimator;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.*;
import javax.media.opengl.awt.GLCanvas;

/**
 *
 * @author kelvio.matias
 */
public class JOGLWindow extends Frame implements GLEventListener {

    private JOGLCallBack callBack;
    
    private JOGLWindow() {
        this.doInit();
    }

    public static JOGLWindow getInstance() {
        return JOGLWindowHolder.INSTANCE;
    }

    private static class JOGLWindowHolder {

        private static final JOGLWindow INSTANCE = new JOGLWindow();
    }
    
    private static final int CANVAS_WIDTH = 640;  // Width of the drawable
    private static final int CANVAS_HEIGHT = 480; // Height of the drawable
    private static final int FPS = 60;   // Animator's target frames per second        
    private boolean firstDraw = true;
    private boolean firstUpdate = true;
    private GL gl;
    // Create a animator that drives canvas' display() at 60 fps. 
    FPSAnimator animator;
    private GLCanvas canvas;

    public GL getGL() {
        return this.gl;
    }

    /**
     *
     */
    private void doInit() {

        // Get the default OpenGL profile that best reflect your running platform.
        GLProfile glp = GLProfile.getDefault();

        // Specifies a set of OpenGL capabilities, based on your profile.
        GLCapabilities caps = new GLCapabilities(glp);

        // Allocate a GLDrawable, based on your OpenGL capabilities.
        canvas = new GLCanvas(caps);

        this.animator = new FPSAnimator(canvas, FPS);
        canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
        canvas.addGLEventListener(this);



        addWindowListener(new WindowAdapter() {     // For the close button

            @Override
            public void windowClosing(WindowEvent e) {
                // Use a dedicate thread to run the stop() to ensure that the
                // animator stops before program exits.
                new Thread() {

                    @Override
                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }.start();
            }
        });
        add(canvas);
        pack();
    }

    public GLCanvas getCanvas() {
        return canvas;
    }

    @Override
    public void setVisible(boolean b) {
        if (b) {
            this.animator.start();
        } else {
            this.animator.stop();
        }
        super.setVisible(b);

    }

    public JOGLCallBack getCallBack() {
        return callBack;
    }

    public void setCallBack(JOGLCallBack callBack) {
        this.callBack = callBack;
    }

    
    
    @Override
    public void init(GLAutoDrawable drawable) {
        this.gl = drawable.getGL();
        if (this.callBack != null) {
            this.callBack.init();
        }
    }

    @Override
    public void display(GLAutoDrawable drawable) {
        if (this.callBack != null) {
            this.callBack.update();
            this.callBack.display();
        }
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
        if (this.callBack != null) {
            this.callBack.reshape(x, y, w, h);
        }
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
        if (this.callBack != null) {
            this.callBack.dispose();
        }
    }
}
